package cn.wolfcode.luowowo.article.service.impl;

import cn.wolfcode.luowowo.article.domain.Scenic;
import cn.wolfcode.luowowo.article.query.ScenicQuery;
import cn.wolfcode.luowowo.article.repository.IScenicRepository;
import cn.wolfcode.luowowo.article.service.IScenicService;
import com.alibaba.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
public class ScenicServiceImpl implements IScenicService {

    @Autowired
    private IScenicRepository scenicRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public List<Scenic> queryScenicTop5ByDestId(Long destId) {
//        Query query = new Query();
//        query.with(PageRequest.of(0,5, Sort.Direction.DESC,"sequence"));
//        query.addCriteria(Criteria.where("destId").is(destId));
//        return mongoTemplate.find(query,Scenic.class);
        AggregationResults<Scenic> aggregationResults = mongoTemplate.aggregate(new TypedAggregation<>(Scenic.class,
                //参数一:要join的集合,参数二:本集合的字段.参数三:join集合的字段,参数四:输出字段名
                Aggregation.lookup("scenic", "refScenicIds", "_id", "refScenics"),
                Aggregation.match(new Criteria().andOperator(Criteria.where("refScenics").ne(Collections.EMPTY_LIST),//排除输出字段为空的结果
                                                Criteria.where("destId").is(destId))),
                Aggregation.sort(Sort.Direction.DESC,"sequence"),//倒序
                Aggregation.limit(5L)//查前5条
                ), Scenic.class);
        return aggregationResults.getMappedResults();
    }

    @Override
    public Scenic getScenicWithRefScenics(ObjectId scenicId) {
        Scenic scenic = this.findById(scenicId);
        for (String s : scenic.getRefScenicIds()) {
            scenic.getRefScenics().add(scenicRepository.findById(s).get());
        }
        return scenic;
    }

    @Override
    public Scenic findById(ObjectId id) {
        return scenicRepository.findById(id.toString()).get();
    }

    @Override
    public void increaseCommentNum(String scenicId) {
        Scenic scenic = this.findById(new ObjectId(scenicId));
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(new ObjectId(scenic.getId())));
        mongoTemplate.updateFirst(query,Update.update("commentNum",scenic.getCommentNum() + 1),Scenic.class);
    }

    @Override
    public List<Scenic> queryHotTop10(Long destId) {
        Query query = new Query();
        query.addCriteria(new Criteria().andOperator(Criteria.where("ishot").is(true),Criteria.where("destId").is(destId),Criteria.where("sequence").is(0)));
        return new ArrayList<>(mongoTemplate.find(query,Scenic.class).subList(0,10));
    }

    @Override
    public Page<Scenic> query(ScenicQuery qo) {
        Query query = new Query();
        if(qo.getKeyword() == null || !StringUtils.hasLength(qo.getKeyword())){
            query.addCriteria(new Criteria().andOperator(Criteria.where("destId").is(qo.getDestId()),Criteria.where("deep").is(1)));
        }else {
            query.addCriteria(new Criteria().andOperator(Criteria.where("destId").is(qo.getDestId()),Criteria.where("deep").is(1),
                    Criteria.where("tags").elemMatch(new Criteria("$eq").is(qo.getKeyword()))));
        }
        long count = mongoTemplate.count(query, Scenic.class);
        if (count == 0){
            return Page.empty();
        }
        PageRequest pageable = PageRequest.of(qo.getCurrentPage() - 1, 15);
        query.with(pageable);
        List<Scenic> scenics = mongoTemplate.find(query, Scenic.class);
        return new PageImpl<>(scenics,pageable,count);
    }
}
